# include <stdio.h>
# include <stdlib.h>
# include <string.h>






// Node declaration
struct node
	{int data;
	struct node *next;}*first=NULL,*nnode,*temp,*t,*te,*last,*firste=NULL;

//Function to calculate length of list
int len(struct node *temp)
	{int count=0;
	while(temp!=NULL)
		{count++;
		temp=temp->next;}
	return count;	
	}
// Functon to return maximum value
int max(struct node *temp)
	{int max,b;
	max=temp->data;
	while(temp!=NULL)
		{		
		temp=temp->next;
		if(temp!=NULL)
			{b=temp->data;}
		if(max<=b)
			{max=b;}
		}
	return max;	
	}

// Function to return minimum value
int min(struct node *temp)
	{int min,b;
	min=temp->data;
	while(temp!=NULL)
		{
		temp=temp->next;
		if(temp!=NULL)
			b=temp->data;
		if(min>b)
			min=b;
		}
	return min;	
	}

// Function to count the occurences of a number

int count(struct node *temp,int value)
	{
	int count=0;
	while(temp!=NULL)
		{
		if(temp->data==value)
			count++;
		temp=temp->next;
		}
	return count;
	}

// Function to append

void append(struct node* temp,int value,struct node *nnode)
	{
	nnode->data=value;
	nnode->next=NULL;	
	while(temp!=NULL)
		{	
		last=temp;
		temp=temp->next; 	
		}
	last->next=nnode;
	}

// Function to remove given element

void remove1(struct node* temp,int value)
	{
	t=temp;
	while((temp->data)!=value)
		{
		t=temp;	
		temp=temp->next;
		}
	t->next=temp->next;
	temp->next=NULL;
	free(temp);
	}

// Function to pop last entered element 


void pop(struct node *temp)
	{
	t=temp;
	while(t!=NULL)
		{	
		last=t;
		t=t->next; 	
		}
	te=temp;
	t=temp->next;
	while((t!=last)&&(te!=last))
		{
		te=t;
		t=t->next;
		}
	te->next=NULL;
	free(te);
	}

// Function to reverse given list

void reverse(struct node *temp)
	{
	t=temp;
	while(t!=NULL)
		{	
		last=t;
		t=t->next; 	
		}
	first=last;
	int i,n=len(temp);
	for(i=0;i<n-1;i++)
		{
		te=temp;
		t=temp->next;
		while((t!=last)&&(te!=last))
			{
			te=t;
			t=t->next;
			}
		last->next=te;
		last=te;
		}
	temp->next=NULL;
	}
	

	
// To return the value when index is given

int index1(struct node *temp,int value)
	{
	int i,n=value;
	if(value<len(temp))
		{
		for(i=0;i<n;i++)
			temp=temp->next;
		return temp->data;
		}
	else
		{		
		printf(" Index greater than length of list");
		return -1;
		}
	}

// To extend a given list

void extend(struct node *temp,struct node *t)
	{
	while(temp!=NULL)
		{
		last=temp;
		temp=temp->next;
		}
	last->next=t;
	}

// To Push at the beginning of he list

void push(struct node *nnode,int value)
	{	
	nnode->data=value;
	nnode->next=first;
	first=nnode;
	}

// To sort

void sort(struct node *temp)
	{
	int a,r;	
	while(temp!=NULL)
		{
		t=temp;
		a=min(t);
		t=temp;
		while(t->data!=a)
			t=t->next;
		r=temp->data;
		temp->data=t->data;
		t->data=r;
		temp=temp->next;
		}
	}


void insert(struct node *temp,struct node *nnode,int value,int pos)
	{
	t=temp;
	last=temp;
	if(pos>len(t))
		printf(" Not valid position\n");
	else if(pos==len(last))
		{
		
		while(temp!=NULL)
			{
			t=temp;
			temp=temp->next;
			}
		nnode->data=value;
		nnode->next=NULL;
		t->next=nnode;
		}
	else if (pos)
		{
		while(pos)
			{
			t=temp;
			temp=temp->next;
			pos--;	
			}
		nnode->data=value;
		nnode->next=t->next;
		t->next=nnode;
		}
	else
		{
		nnode->data=value;
		nnode->next=temp;
		first=nnode;
		}
	}
// Initial function to create list	

void add(struct node *nnode,int value)
	{nnode->data=value;
	nnode->next=first;
	first=nnode;}

// Display list

void show(struct node *temp)
	{	
		printf("[ ");
		while(temp!=NULL)
		{
		printf("%d ",temp->data);
		temp=temp->next;
		}
		printf("]\n");
	}

// Menu
	
int  main(void)
	{
	int ans,choice,value,pos;
	do
		{
		do	{	
			nnode=malloc(sizeof(struct node));
			printf("Enter data\n");
			scanf("%d",&value);
			add(nnode,value);
			printf("Do you want to enter more?\n");
			scanf("%d",&ans);}while(ans);
		
		temp=first;
		reverse(temp);
		printf(" Enter operation number according to the menu \n");
		printf(" Find Length of the list :                    1\n");
		printf(" Find Maximum element of the list :           2\n");
		printf(" Find Minimum element of the list :           3\n");
		printf(" Find Reverse of the list :                   4\n");
		printf(" Find Count of the given element in the list: 5\n");
		printf(" Find Value using index in the list :         6\n");
		printf(" Pop last element of the list :               7\n");
		printf(" Append element into the list :               8\n");	
		printf(" Remove element from the list :               9\n");
		printf(" Extend a given list:	                      10\n");
		printf(" Push at the begining an element:             11\n");
		printf(" Sort the given list :			      12\n");
		printf(" Insert an element at given position:         13\n");
		printf(" Show List:				      14\n");	
				
		do{	
			printf("Enter choice\n");
			scanf("%d",&choice);
			switch(choice)
				{		
				case 1:{temp=first;printf("%d\n",len(temp));break;}

				case 2:{temp=first;printf("%d\n",max(temp));break;}

				case 3:{temp=first;printf("%d\n",min(temp));break;}

				case 4:{temp=first;reverse(temp);temp=first;show(temp);break;}

				case 5:{temp=first;printf("Enter count value");scanf("%d",&value);printf("%d\n",count(temp,value));break;}

				case 6:{temp=first;printf("Enter index value");scanf("%d",&value);printf("%d\n",index1(temp,value));break;}

				case 7:{temp=first;pop(temp);temp=first;show(temp);break;}

				case 8:{temp=first;printf("Enter value to append");scanf("%d",&value);nnode=malloc(sizeof(struct node)); 		                                append(temp,value,nnode);temp=first;show(temp);break;}

				case 9:{temp=first;printf("Enter value to remove");scanf("%d",&value);remove1(temp,value);temp=first;show(temp);break;}

				case 10:{
					do{	
						nnode=malloc(sizeof(struct node));
						printf("Enter data\n");
						scanf("%d",&value);
						nnode->data=value;
						nnode->next=firste;
						firste=nnode;
						printf("Do you want to enter more?\n");
						scanf("%d",&ans);}while(ans);
				
					temp=firste;				
					t=temp;
					while(t!=NULL)
					{	
					last=t;
					t=t->next; 	
					}
					firste=last;
					int i,n=len(temp);
					for(i=0;i<n-1;i++)
						{
						te=temp;
						t=temp->next;
						while((t!=last)&&(te!=last))
							{
							te=t;
							t=t->next;
							}
						last->next=te;
						last=te;
						}
					temp->next=NULL;
					temp=first; t=firste;
					extend(temp,t);
					temp=first;
					show(temp);
					break;
					}
						
				case 11:{
					nnode=malloc(sizeof(struct node));
					printf("Enter value to push");scanf("%d",&value);
					push(nnode,value);
					temp=first;
					show(temp);
					break;
					}				

				case 12:{temp=first;sort(temp);temp=first;
					printf("Do you want to sort in ascending(1) or descending(2) order?");
					scanf("%d",&choice);
					if(choice==1)
						show(temp);
					else
						{
						reverse(temp);
						temp=first;
						show(temp);
						}
					break;
					}				

				case 13:{
					temp=first;
					printf("Enter element and position to insert at");	
					scanf("%d %d",&value,&pos);
					nnode=malloc(sizeof(struct node));
					insert(temp,nnode,value,pos);
					temp=first;
					show(first);
					break;
					}

				case 14:{temp=first;show(temp);break;}
				}

			printf("Do you want to repeat from given menu?\n");
			scanf("%d",&ans);
		  }while(ans);
		
		printf("Do you want to exit or to start afresh?\n");
		scanf("%d",&ans);
		first=NULL;
		}while(ans);
	return 0;}
